package cn.edu.sjtu.se.dslab.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.edu.sjtu.se.dslab.action.bean.PageBean;
import cn.edu.sjtu.se.dslab.auth.CommonVariableModel;
import cn.edu.sjtu.se.dslab.component.aadl.AADLGenerator;
import cn.edu.sjtu.se.dslab.component.aadl.AADLLink;
import cn.edu.sjtu.se.dslab.component.aadl.AADLLoger;
import cn.edu.sjtu.se.dslab.component.aadl.AADLModel;
import cn.edu.sjtu.se.dslab.component.aadl.AADLNode;
import cn.edu.sjtu.se.dslab.component.aadl.AADLParser;
import cn.edu.sjtu.se.dslab.component.aadl.AADLTemplate;
import cn.edu.sjtu.se.dslab.component.aadl.AAXLParser;
import cn.edu.sjtu.se.dslab.component.data.AvionicsEquipment;
import cn.edu.sjtu.se.dslab.exception.DBException;
import cn.edu.sjtu.se.dslab.project.PGroup;
import cn.edu.sjtu.se.dslab.project.Project;
import cn.edu.sjtu.se.dslab.rhapsody.entity.Agent;
import cn.edu.sjtu.se.dslab.rhapsody.service.RhapsodyFileService;
import cn.edu.sjtu.se.dslab.service.IAADLModelService;
import cn.edu.sjtu.se.dslab.service.IAADLTemplateService;
import cn.edu.sjtu.se.dslab.service.IAadlLogerService;
import cn.edu.sjtu.se.dslab.service.IAvionicsEquipmentService;
import cn.edu.sjtu.se.dslab.service.IPGroupService;
import cn.edu.sjtu.se.dslab.service.IProjectService;
import cn.edu.sjtu.se.dslab.util.Const;
import cn.edu.sjtu.se.dslab.util.MD5;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sun.jmx.snmp.Timestamp;

@Controller
@RequestMapping(value = "/aadl")
public class AADLController {
	@Resource(name = "avionicsEquipmentService")
	IAvionicsEquipmentService avionicsEquipmentService;

	@Resource(name = "aadlTemplateService")
	IAADLTemplateService aadlTemplateService;

	@Resource(name = "aadlModelService")
	IAADLModelService aadlModelService;

	@Resource(name = "projectService")
	IProjectService projectService;

	@Resource(name = "aadlParser")
	AADLParser aadlParser;

	@Resource(name = "aaxlParser")
	AAXLParser aaxlParser;
	
	@Resource(name="pgroupService")
	IPGroupService pgroupService;
	
	@Resource(name="rhapsodyFileService")
	RhapsodyFileService rhapsodyFileService;
	
	@Resource(name="aadlLogerService")
	IAadlLogerService aadlLogerService;

	private final static String NAME = "name";

	private final static String URI = "uri";

	private final static String DESCRIPTION = "description";

	/**
	 * 所有编辑aadl模型的入口
	 * @return
	 */
	@RequestMapping(value = { "/edit", "model/edit", "template/edit" }, method = RequestMethod.GET)
	public ModelAndView editAADL(@RequestParam(value = "projectId",required=false) String projectId,HttpServletResponse response) {
		// ////////////////////////////////////
		ModelAndView model = new ModelAndView();
		System.out.println("edit projectId:" + projectId);
		if (projectId != null && !projectId.equals("")) {
			// 插入session
			System.out.println("insert cookie");
			Cookie idCookie = new Cookie("projectId", projectId); //bake cookie	
			idCookie.setMaxAge(6000);
			response.addCookie(idCookie); //put cookie in response
			Project project = projectService.getProjectById(Long.parseLong(projectId));
			model.addObject("project", project);
		} else {
			Cookie idCookie = new Cookie("projectId", ""+0); //bake cookie	
			response.addCookie(idCookie); //put cookie in response
		}
		Cookie typeCookie = new Cookie("type", "create"); //bake cookie	
		response.addCookie(typeCookie); //put cookie in response
		model.setViewName("edit_aadl_nomenu");
		// 内部设备-->inner device
		List<AvionicsEquipment> innerDevices = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_INNER_DEVICE);
		model.addObject("innerDevices", innerDevices);

		// 外部设备-->inner device
		List<AvionicsEquipment> outterDevices = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_OUTTER_DEVICE);
		model.addObject("outterDevices", outterDevices);

		// 总线
		List<AvionicsEquipment> buses = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_BUS);
		model.addObject("buses", buses);
		
		//代理
		if (projectId != null && !projectId.equals("")) {
			List<Agent> agentList = rhapsodyFileService.getAllAgents(Long.parseLong(projectId));
			//List<Agent> agentList = new ArrayList<Agent>();
			//BusAgent busAgent = new BusAgent();
//			busAgent.setName("bus1");
//			DisplayAgent displayAgent = new DisplayAgent();
//			displayAgent.setName("display2");
//			ControlAgent controlAgent = new ControlAgent();
//			controlAgent.setName("control3");
//			agentList.add(busAgent);
//			agentList.add(displayAgent);
//			agentList.add(controlAgent);
			model.addObject("agentList", agentList);
		}
		
		//pgroup
		List<PGroup> groups = pgroupService.getPGroupList();
		model.addObject("groups", groups);
		
		
		model.addObject("nodeJson", "null");
		model.addObject("linkJson", "null");
		return model;
	}

	/**
	 * 为项目选择系统架构的入口
	 * @return
	 */
	@RequestMapping(value = "/schedule", method = { RequestMethod.POST,
			RequestMethod.GET })
	public String scheduleAADL(
			@RequestParam(value = "projectId", required = false) String projectId,
			HttpServletResponse response) {
		Project project = projectService.getProjectById(Long.parseLong(projectId));
		if (project.getModel() != null) {
			return "redirect:/"+project.getModel().getUri().replace(':', '/');
		}else {
			return "redirect:/aadl/template/select?projectId="+projectId;
		}
	}
	
	/**
	 * 删除项目已定义的架构实例
	 * @return
	 */
	@RequestMapping(value = "/delete", method = { RequestMethod.GET })
	@ResponseBody
	public String deleteAADLByProjectId(
			@RequestParam(value = "projectId", required = false) String projectId) {
		System.out.println("projectId:"+projectId);
		Project project = projectService.getProjectById(Long.parseLong(projectId));
		if (project != null) {
			AADLModel model = project.getModel();
			model.setProject(null);
			aadlModelService.updateAADLModel(model);
			project.setModel(null);
			projectService.updateProject(project);
		}
		return "success";
	}
	
	
	/**
	 * 为项目选择架构模型的入口
	 * @param projectId-->写入cookie
	 * @param modelMap
	 * @return
	 */
	@RequestMapping(value = "/template/select", method = { RequestMethod.POST,
			RequestMethod.GET })
	public ModelAndView selectAADLTemplate(
			@RequestParam(value = "projectId", required = false) String projectId,
			HttpServletResponse response) {
		ModelAndView model = new ModelAndView();
		System.out.println("start projectId:" + projectId);
		if (projectId != null && !projectId.equals("")) {
			// 插入session
			System.out.println("insert cookie");
			Cookie idCookie = new Cookie("projectId", projectId); //bake cookie	
			idCookie.setMaxAge(6000);
			response.addCookie(idCookie); //put cookie in response
		} else {
			Cookie idCookie = new Cookie("projectId", ""+0); //bake cookie	
			response.addCookie(idCookie); //put cookie in response
		}
		Cookie nameCookie = new Cookie("query_name", ""); 
		response.addCookie(nameCookie);
		Cookie descCookie = new Cookie("query_des", ""); 
		response.addCookie(descCookie);
		Cookie groupCookie = new Cookie("groupid", ""); 
		response.addCookie(groupCookie);
		List<PGroup> groups = pgroupService.getPGroupList();
		model.addObject("groups", groups);
		model.setViewName("aadl_select");
		return model;
	}
	
	
	/**
	 * 检索查找，显示架构模板列表
	 * @return
	 */
	@RequestMapping(value = "/template", method = { RequestMethod.POST,
			RequestMethod.GET })
	public ModelAndView queryAADLTemplate(@CookieValue(value = "template_name", defaultValue = "") String templateName,
			@RequestParam(value = "name", required = false) String name,
			@RequestParam(value = "description", required = false) String description,
			@CookieValue(value = "template_des", defaultValue = "") String templateDes,
			@RequestParam(value = "groupid", required = false, defaultValue = "0") String _groupid,
			@CookieValue(value = "template_groupid", defaultValue = "0") String groupid,
			@RequestParam(value = "pageNum", defaultValue = "1") int pageNum,HttpServletResponse response) throws DBException{
		System.out.println("pageNUm:"+pageNum+"|query_name:"+name+"|query_des:"+description+"|groupid:"+_groupid);
		ModelAndView model = new ModelAndView();
		if (templateName.equals("")) {
			templateName = name;
			Cookie nameCookie = new Cookie("template_name", templateName); //bake cookie	
			response.addCookie(nameCookie); //put cookie in response
			
		}
		if (templateDes.equals("")) {
			templateDes = description;
			Cookie desCookie = new Cookie("template_des", templateDes); //bake cookie	
			response.addCookie(desCookie); //put cookie in response 
		}
		//if (groupid.equals("0")) {
		groupid = _groupid;
		Cookie groupCookie = new Cookie("template_groupid", groupid); //bake cookie	
		response.addCookie(groupCookie); //put cookie in response 
		//}
		PageBean<AADLTemplate> bean = aadlTemplateService.getPageBeanByAttr(pageNum, templateName, templateDes,Long.parseLong(_groupid));
		model.addObject("bean", bean);
		List<PGroup> groups = pgroupService.getPGroupList();
		model.addObject("groups", groups);
		Subject user = SecurityUtils.getSubject();
		if (user!= null && user.getPrincipals() != null) {
			CommonVariableModel commonVariableModel = (CommonVariableModel) user.getPrincipals()
					.getPrimaryPrincipal();
			model.addObject("id", commonVariableModel.getUser().getId());
		}
		model.setViewName("aadl_template_list");
		return model;
	}

	/**
	 * 检索aadl模板
	 * @param pageNUm
	 * @param name
	 * @param description
	 * @return
	 */
	@RequestMapping(value = "/template/query", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> queryAADLTemplate(
			@RequestParam(value = "pageNum", defaultValue = "1") int pageNUm,
			@RequestParam(value = "query_name", defaultValue = "") String name,
			@RequestParam(value = "query_des", defaultValue = "") String description,
			@RequestParam(value = "groupid", defaultValue = "0") String groupid) {
		System.out.println("pageNUm:"+pageNUm+"|query_name:"+name+"|query_des:"+description+"|groupid:"+groupid);
		Map<String, Object> modelMap = new HashMap<String, Object>(4);
		try {
			PageBean<AADLTemplate> bean = aadlTemplateService
					.getPageBeanByAttr(pageNUm, name, description,Long.parseLong(groupid));
			List<Map<String, String>> data = new ArrayList<Map<String, String>>();
			if (bean != null && bean.getList() != null) {
				for (int i = 0; i < bean.getList().size(); i++) {
					Map<String, String> map = new HashMap<String, String>();
					map.put(URI,
							bean.getList().get(i).getUri().replace(":", "/"));
					map.put(NAME, bean.getList().get(i).getName());
					map.put(DESCRIPTION, bean.getList().get(i).getDescription());
					data.add(map);
				}
				modelMap.put("currentNum", bean.getCurrentPage());
				modelMap.put("totalNum", bean.getTotalPage());
				modelMap.put("data", data);
				modelMap.put("success", "true");
			} else {
				modelMap.put("success", "false");
			}
			return modelMap;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			modelMap.put("success", "false");
		}
		return modelMap;
	}
    /**
     * 提交aadl模板或者应用实例类型-->清理cookie中projectId的值
     * @param aadl_xml
     * @param projectId
     * @return
     * @throws IOException
     */
	@RequestMapping(value = "/model/edit", method = RequestMethod.POST)
	public String editAADLModel(String aadl_xml,
			@RequestParam(value ="projectId") String projectId,HttpServletResponse response) throws IOException {
		System.out.println("model edit projectId:" + projectId);
		String aadlPath = Const.AADL_GENERATE_PATH;
		String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH + aadlPath;
		Cookie projCookie = new Cookie("projectId", "0"); //bake cookie	
		response.addCookie(projCookie); //put cookie in response 
		String temp = "aadl_model" + new Timestamp().toString();
		MD5 md5 = new MD5();
		String fileName = md5.getMD5ofStr(temp).substring(0, 8);
		String filePath = aadlRealPath + "/" + fileName + ".xml";
		while (new File(filePath).exists()) {
			temp = "aadl_model" + new Timestamp().toString();
			fileName = md5.getMD5ofStr(temp).substring(0, 8);
			filePath = aadlRealPath + "/" + fileName + ".xml";
		}
		File file = getFile(filePath);
		FileWriter fWriter = null;
		try {
			fWriter = new FileWriter(file);
			fWriter.write(aadl_xml);

			AADLGenerator generator = new AADLGenerator();
			generator.generateAADL(aadl_xml, fileName + ".aadl");

			AADLModel model = new AADLModel();
			model.setAadlPath(aadlPath + fileName + ".aadl");
			model.setXmlPath(aadlPath + fileName + ".xml");
			Subject user = SecurityUtils.getSubject();
			if (user!= null && user.getPrincipals() != null) {
				CommonVariableModel commonVariableModel = (CommonVariableModel) user.getPrincipals()
						.getPrimaryPrincipal();
				model.setOwner(commonVariableModel.getUser());
			}
			Project project = projectService.getProjectById(Long
					.parseLong(projectId));
			if (project == null) {
					aadlModelService.addAADLModel(model);
					return "redirect:/home"/* + model.getUri().replace(":", "/")*/;
			}
			///////////////////////////////////////////////
			String projectName = project.getName().replace(" ", "_");
			aaxlParser.parseAAXL(aadl_xml, aadlRealPath + fileName + ".aaxl",
					projectName);
			model.setAaxlPath(aadlPath + fileName + ".aaxl");
			// /////////////////////////////////////////////
			if (project != null) {
				if (project.getModel() != null) {
					AADLModel model2 = project.getModel();
					model2.setAadlPath(model.getAadlPath());
					model2.setXmlPath(model.getXmlPath());
					aadlModelService.updateAADLModel(model2);				
				} else {
					model.setProject(project);
					aadlModelService.addAADLModel(model);
				}
				//return "redirect:/home"/* + model.getUri().replace(":", "/")*/;
			}
			
		} finally {
			fWriter.flush();
			fWriter.close();
		}
		return "redirect:/home";
	}

	/**
	 * 提交定义模板的入口-->清理cookie中projectId的值
	 * @param aadl_xml
	 * @param name
	 * @param description
	 * @param projectId
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/template/edit", method = RequestMethod.POST)
	public String editAADLTemplate(String aadl_xml, String name,long groupid,
			String description, @RequestParam(value ="projectId", defaultValue = "0") String projectId
			,HttpServletResponse response) throws IOException {
		String aadlPath = Const.AADL_GENERATE_PATH;
		String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH + aadlPath;
		Cookie projCookie = new Cookie("projectId", "0"); //bake cookie	
		response.addCookie(projCookie); //put cookie in response 
		String temp = "aadl_model" + new Timestamp().toString();
		MD5 md5 = new MD5();
		String fileName = md5.getMD5ofStr(temp).substring(0, 8);
		String filePath = aadlRealPath + "/" + fileName + ".xml";

		while (new File(filePath).exists()) {
			temp = "aadl_model" + new Timestamp().toString();
			fileName = md5.getMD5ofStr(temp).substring(0, 8);
			filePath = aadlRealPath + "/" + fileName + ".xml";
		}
		File file = getFile(filePath);
		FileWriter fWriter = null;
		try {
			fWriter = new FileWriter(file);
			fWriter.write(aadl_xml);

			AADLGenerator generator = new AADLGenerator();
			generator.generateAADL(aadl_xml, fileName + ".aadl");
			AADLModel model = new AADLModel();
			model.setAadlPath(aadlPath + fileName + ".aadl");
			model.setXmlPath(aadlPath + fileName + ".xml");
			
			Subject user = SecurityUtils.getSubject();
			if (user!= null && user.getPrincipals() != null) {
				CommonVariableModel commonVariableModel = (CommonVariableModel) user.getPrincipals()
						.getPrimaryPrincipal();
				model.setOwner(commonVariableModel.getUser());
			}
			aadlModelService.addAADLModel(model);
			//Subject user = SecurityUtils.getSubject();
			//if (user!= null && user.getPrincipals() != null) {
			//	CommonVariableModel commonVariableModel = (CommonVariableModel) user.getPrincipals()
			///			.getPrimaryPrincipal();
			//	model.setOwner(commonVariableModel.getUser());
			//}
			//String result = "";
			//Project project = projectService.getProjectById(Long
			//		.parseLong(projectId));
			// /////////////////////////////////////////////
			/*String projectName = project.getName().replace(" ", "_");
			aaxlParser.parseAAXL(aadl_xml, aadlRealPath + fileName + ".aaxl",
					projectName);
			model.setAaxlPath(aadlPath + fileName + ".aaxl");*/
			// /////////////////////////////////////////////
			//if (project != null) {
			
			//	if (project.getModel() != null) {
			//		AADLModel model2 = project.getModel();
			//		model2.setProject(null);
			//		aadlModelService.updateAADLModel(model2);
			//	}
			//	model.setProject(project);
			//	aadlModelService.updateAADLModel(model);
			//	result = "redirect:/project/list?projectId=" + projectId;
			//} else {
			//	aadlModelService.addAADLModel(model);
			//	result = "redirect:/aadl/template";
			//}
			PGroup group = pgroupService.getPGroupById(groupid);
			AADLTemplate aadlTemplate = new AADLTemplate();
			aadlTemplate.setDescription(description);
			aadlTemplate.setGroup(group);
			aadlTemplate.setName(name);
			aadlTemplate.setModel(model);
			aadlTemplateService.addAADLTemplate(aadlTemplate);
			return "redirect:/aadl/template";
		} finally {
			fWriter.flush();
			fWriter.close();
		}
	}

	/**
	 * 查看应用实例的架构图
	 * @param uri
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/model/{uri}", method = RequestMethod.GET)
	public ModelAndView getAADL(@PathVariable(value = "uri") String uri)
			throws IOException {
		ModelAndView model = new ModelAndView();
		model.setViewName("aadl_detail_nomenu");
		AADLModel aadlModel = aadlModelService.getAADLModelByUri(uri);
		if (aadlModel != null) {
			String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH
					+ aadlModel.getXmlPath();
			File file = getFile(aadlRealPath);
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
					.create();
			List<AADLNode> nodeList = aadlParser.parseAADLToNode(file);
			List<AADLLink> linkList = aadlParser.parseAADLToLink(file);
			String nodeJson = gson.toJson(nodeList);
			String linkJson = gson.toJson(linkList);
			model.addObject("nodeJson", nodeJson);
			model.addObject("linkJson", linkJson);
			int width = aadlParser.parseAADLToWidth(file);
			int height = aadlParser.parseAADLToHeight(file);
			model.addObject("width", width);
			model.addObject("height", height);
			String aadlCodeRealPath = Const.ABSOLUTE_GENERATE_PATH
					+ aadlModel.getAadlPath();
			File codeFile = getFile(aadlCodeRealPath);
			StringBuffer codebBuffer = new StringBuffer();
			List<String> codeList = FileUtils.readLines(codeFile);
			for (String string : codeList) {
				codebBuffer.append(string + "\n");
			}
			model.addObject("code", codebBuffer.toString());
			model.addObject("uri",aadlModel.getUri());
			if (aadlModel.getLogers() != null) {
				model.addObject("logerList", aadlModel.getLogers());
			}
		}
		return model;
	}

	
	/**
	 * 查看应用实例的aadl代码
	 * @param uri
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/model/{uri}/aadl", method = RequestMethod.GET)
	public ModelAndView showAADLCode(@PathVariable(value = "uri") String uri)
			throws IOException {
		ModelAndView model = new ModelAndView();
		model.setViewName("aadl_code");
		AADLModel aadlModel = aadlModelService.getAADLModelByUri(uri);
		if (aadlModel != null) {
			String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH
					+ aadlModel.getAadlPath();
			File file = getFile(aadlRealPath);
			StringBuffer codebBuffer = new StringBuffer();
			List<String> codeList = FileUtils.readLines(file);
			for (String string : codeList) {
				codebBuffer.append(string + "\n");
			}
			model.addObject("code", codebBuffer.toString());
			model.addObject("item", aadlModel.getProject());
		}
		return model;
	}

	/**
	 * 下载aadl代码
	 * @param uri
	 * @param response
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	@RequestMapping(value = "/model/{uri}/aadl/download", method = RequestMethod.GET)
	public void downloadAADLCodeByUri(@PathVariable(value = "uri") String uri,
			HttpServletResponse response) throws FileNotFoundException,
			IOException {
		AADLModel aadlModel = aadlModelService.getAADLModelByUri(uri);
		if (aadlModel != null) {
			String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH
					+ aadlModel.getAadlPath();
			File file = getFile(aadlRealPath);

			InputStream is = new FileInputStream(file);
			// set content attributes for the response
			response.setContentType("application/octet-stream");
			response.setContentLength((int) file.length());
			// set headers for the response
			String headerKey = "Content-Disposition";
			String headerValue = null;
			if (aadlModel.getProject() != null) {
				headerValue = String.format("attachment; filename=\"%s\"",
						aadlModel.getProject().getName() + ".aadl");
			}else {
				headerValue = String.format("attachment; filename=\"%s\"",
						System.currentTimeMillis() + ".aadl");
			}
			response.setHeader(headerKey, headerValue);
			IOUtils.copy(is, response.getOutputStream());
			response.flushBuffer();
		}
	}

	/**
	 * 查看架构模板的架构
	 * @param uri
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/template/{uri}", method = RequestMethod.GET)
	public ModelAndView getAADLTemplate(@PathVariable(value = "uri") String uri)
			throws IOException {
		ModelAndView model = new ModelAndView();
		model.setViewName("aadl_detail_nomenu");
		AADLTemplate aadlTemplate = aadlTemplateService
				.getAADLTemplateByUri(uri);
		AADLModel aadlModel = aadlTemplate.getModel();
		if (aadlModel != null) {
			String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH
					+ aadlModel.getXmlPath();
			File file = getFile(aadlRealPath);
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
					.create();
			List<AADLNode> nodeList = aadlParser.parseAADLToNode(file);
			List<AADLLink> linkList = aadlParser.parseAADLToLink(file);
			int width = aadlParser.parseAADLToWidth(file);
			int height = aadlParser.parseAADLToHeight(file);
			String nodeJson = gson.toJson(nodeList);
			String linkJson = gson.toJson(linkList);
			model.addObject("nodeJson", nodeJson);
			model.addObject("linkJson", linkJson);
			model.addObject("width", width);
			model.addObject("height", height);
			model.addObject("aadlTemplate", aadlTemplate);
			if (aadlModel.getLogers() != null) {
				model.addObject("logerList", aadlModel.getLogers());
			}
			String aadlCodeRealPath = Const.ABSOLUTE_GENERATE_PATH
						+ aadlModel.getAadlPath();
			File codeFile = getFile(aadlCodeRealPath);
			StringBuffer codebBuffer = new StringBuffer();
			List<String> codeList = FileUtils.readLines(codeFile);
			for (String string : codeList) {
					codebBuffer.append(string + "\n");
			}
			model.addObject("code", codebBuffer.toString());
			model.addObject("uri",aadlModel.getUri());
		}
		return model;
	}

	/**
	 * 继承复用架构模板的入口
	 * @param uri
	 * @param response
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/template/{uri}/inherit", method = RequestMethod.GET)
	public ModelAndView inheritAADLTemplate(
			@PathVariable(value = "uri") String uri,HttpServletResponse response,
			@CookieValue(value = "projectId", required=false, defaultValue = "0") String projectId) throws IOException {
		Cookie typeCookie = new Cookie("type", "create"); //bake cookie	
		response.addCookie(typeCookie); //put cookie in response
		ModelAndView model = new ModelAndView();
		model.setViewName("edit_aadl_nomenu");
		if (projectId != null && !projectId.equals("")) {
			System.out.println("get the projectId:"+projectId);
			Project project = projectService.getProjectById(Long.parseLong(projectId));
			model.addObject("project", project);
		} 
		AADLTemplate aadlTemplate = aadlTemplateService
				.getAADLTemplateByUri(uri);
		AADLModel aadlModel = aadlTemplate.getModel();
		// 内部设备-->inner devices
		List<AvionicsEquipment> innerDevices = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_INNER_DEVICE);
		model.addObject("innerDevices", innerDevices);

		// 外部设备-->inner devices
		List<AvionicsEquipment> outterDevices = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_OUTTER_DEVICE);
		model.addObject("outterDevices", outterDevices);

		// 总线
		List<AvionicsEquipment> buses = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_BUS);
		model.addObject("buses", buses);

		//pgroup
		List<PGroup> groups = pgroupService.getPGroupList();
		model.addObject("groups", groups);
		
		//代理
		if (projectId != null && !projectId.equals("")) {
			List<Agent> agentList = rhapsodyFileService.getAllAgents(Long.parseLong(projectId));
//			List<Agent> agentList = new ArrayList<Agent>();
//			BusAgent busAgent = new BusAgent();
//			busAgent.setName("bus1");
//			DisplayAgent displayAgent = new DisplayAgent();
//			displayAgent.setName("display2");
//			ControlAgent controlAgent = new ControlAgent();
//			controlAgent.setName("control3");
//			agentList.add(busAgent);
//			agentList.add(displayAgent);
//			agentList.add(controlAgent);
			model.addObject("agentList", agentList);
		}
		
		
		String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH
				+ aadlModel.getXmlPath();
		File file = getFile(aadlRealPath);
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
				.create();
		List<AADLNode> nodeList = aadlParser.parseAADLToNode(file);
		List<AADLLink> linkList = aadlParser.parseAADLToLink(file);
		String nodeJson = gson.toJson(nodeList);
		String linkJson = gson.toJson(linkList);
		model.addObject("nodeJson", nodeJson);
		model.addObject("linkJson", linkJson);
		return model;
	}
	
	@RequestMapping(value = "/template/{uri}/delete", method = RequestMethod.GET)
	public String deleteAADLTemplate(
			@PathVariable(value = "uri") String uri) throws IOException {
		AADLTemplate aadlTemplate = aadlTemplateService
				.getAADLTemplateByUri(uri);
		aadlTemplateService.deleteAADLTemplate(aadlTemplate);
		return "redirect:/aadl/template";
	}

	/**
	 * 为项目更新架构模型实例的入口 
	 * @param uri
	 * @param projectId
	 * @param modelMap
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/model/{uri}/update", method = RequestMethod.GET)
	public ModelAndView updateAADL(
			@PathVariable(value = "uri") String uri,
			@RequestParam(value = "projectId", required = false) String projectId,HttpServletResponse response) throws IOException {
		System.out.println("update aadl--projectId:" + projectId);
		ModelAndView model = new ModelAndView();
		if (projectId != null && !projectId.equals("")) {
			// 插入session
			System.out.println("insert cookie");
			Cookie idCookie = new Cookie("projectId", projectId); //bake cookie	
			idCookie.setMaxAge(6000);
			response.addCookie(idCookie); //put cookie in response
			Project project = projectService.getProjectById(Long.parseLong(projectId));
			model.addObject("project", project);
		} else {
			Cookie idCookie = new Cookie("projectId", ""+0); //bake cookie	
			response.addCookie(idCookie); //put cookie in response
		}
		Cookie typeCookie = new Cookie("type", "update"); //bake cookie	
		response.addCookie(typeCookie); //put cookie in response
		Cookie uriCookie = new Cookie("uri", uri); //bake cookie	
		response.addCookie(uriCookie); //put cookie in response
		model.setViewName("edit_aadl_nomenu");
		// 内部设备
		List<AvionicsEquipment> innerDevices = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_INNER_DEVICE);
		model.addObject("innerDevices", innerDevices);

		// 外部设备
		List<AvionicsEquipment> outterDevices = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_OUTTER_DEVICE);
		model.addObject("outterDevices", outterDevices);

		// 总线
		List<AvionicsEquipment> buses = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_BUS);
		model.addObject("buses", buses);
		
		//pgroup
		List<PGroup> groups = pgroupService.getPGroupList();
		model.addObject("groups", groups);

		//代理
		if (projectId != null && !projectId.equals("")) {
			List<Agent> agentList = rhapsodyFileService.getAllAgents(Long.parseLong(projectId));
			model.addObject("agentList", agentList);
		}
		
		AADLModel aadlModel = aadlModelService.getAADLModelByUri(uri);
		String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH
				+ aadlModel.getXmlPath();
		File file = getFile(aadlRealPath);
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
				.create();
		List<AADLNode> nodeList = aadlParser.parseAADLToNode(file);
		List<AADLLink> linkList = aadlParser.parseAADLToLink(file);
		String nodeJson = gson.toJson(nodeList);
		String linkJson = gson.toJson(linkList);
		model.addObject("nodeJson", nodeJson);
		model.addObject("linkJson", linkJson);
		if (aadlModel.getLogers() != null) {
			model.addObject("logerList", aadlModel.getLogers());
		}
		return model;
	}
	
	/**
	 * 为项目更新架构模型的提交入口 
	 * @param uri
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/model/{uri}/update", method = RequestMethod.POST)
	public String updateAADLPost(@PathVariable(value = "uri") String uri,String aadl_xml,
			@RequestParam(value = "projectId", required = false) String projectId,
			String logerInfo,
			HttpServletResponse response) throws IOException {
		String aadlPath = Const.AADL_GENERATE_PATH;
		String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH + aadlPath;
		Cookie uriCookie = new Cookie("uri", ""); //bake cookie	
		response.addCookie(uriCookie); //put cookie in response
		Cookie idCookie = new Cookie("projectId", ""+0); //bake cookie	
		response.addCookie(idCookie); //put cookie in response
		Cookie typeCookie = new Cookie("type", ""); //bake cookie	
		response.addCookie(typeCookie); //put cookie in response 
		String temp = "aadl_model" + new Timestamp().toString();
		MD5 md5 = new MD5();
		String fileName = md5.getMD5ofStr(temp).substring(0, 8);
		String filePath = aadlRealPath + "/" + fileName + ".xml";
		
		AADLModel model = aadlModelService.getAADLModelByUri(uri);
		while (new File(filePath).exists()) {
			temp = "aadl_model" + new Timestamp().toString();
			fileName = md5.getMD5ofStr(temp).substring(0, 8);
			filePath = aadlRealPath + "/" + fileName + ".xml";
		}
		File file = getFile(filePath);
		FileWriter fWriter = null;
		try {
			fWriter = new FileWriter(file);
			fWriter.write(aadl_xml);

			AADLGenerator generator = new AADLGenerator();
			generator.generateAADL(aadl_xml, fileName + ".aadl");
			model.setAadlPath(aadlPath + fileName + ".aadl");
			model.setXmlPath(aadlPath + fileName + ".xml");
			aadlModelService.updateAADLModel(model);
			AADLLoger loger = new AADLLoger();
			loger.setLogInfo(logerInfo);
			loger.setModel(model);
			loger.setTime(new Date());
			Subject user = SecurityUtils.getSubject();
			if (user!= null && user.getPrincipals() != null) {
				CommonVariableModel commonVariableModel = (CommonVariableModel) user.getPrincipals()
						.getPrimaryPrincipal();
				loger.setOperator(commonVariableModel.getUser());
			}
			aadlLogerService.addAadlLoger(loger);
			return "redirect:/home";
		} finally {
			fWriter.flush();
			fWriter.close();
		}
	}
	
	
	/**
	 * 更新架构模板的入口 
	 * @param uri
	 * @param projectId
	 * @param modelMap
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/template/{uri}/update", method = RequestMethod.GET)
	public ModelAndView updateAADLTemplate(
			@PathVariable(value = "uri") String uri,HttpServletResponse response) throws IOException {
		
		System.out.println("insert cookie");
		Cookie idCookie = new Cookie("uri", uri); //bake cookie	
		idCookie.setMaxAge(6000);
		response.addCookie(idCookie); //put cookie in response
		Cookie typeCookie = new Cookie("type", "update"); //bake cookie	
		response.addCookie(typeCookie); //put cookie in response 
		Cookie projectCookie = new Cookie("projectId", ""+0); //bake cookie	
		response.addCookie(projectCookie); //put cookie in response
		ModelAndView model = new ModelAndView();
		model.setViewName("edit_aadl_nomenu");
		// 内部设备
		List<AvionicsEquipment> innerDevices = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_INNER_DEVICE);
		model.addObject("innerDevices", innerDevices);

		// 外部设备
		List<AvionicsEquipment> outterDevices = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_OUTTER_DEVICE);
		model.addObject("outterDevices", outterDevices);

		// 总线
		List<AvionicsEquipment> buses = avionicsEquipmentService
				.getAvionicsEquipmentByType(AvionicsEquipment.EQUIPMENT_TYPE_BUS);
		model.addObject("buses", buses);
		//pgroup
		List<PGroup> groups = pgroupService.getPGroupList();
		model.addObject("groups", groups);
		
		AADLTemplate template = aadlTemplateService.getAADLTemplateByUri(uri);
		AADLModel aadlModel = template.getModel();
		String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH
				+ aadlModel.getXmlPath();
		File file = getFile(aadlRealPath);
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
				.create();
		List<AADLNode> nodeList = aadlParser.parseAADLToNode(file);
		List<AADLLink> linkList = aadlParser.parseAADLToLink(file);
		String nodeJson = gson.toJson(nodeList);
		String linkJson = gson.toJson(linkList);
		model.addObject("nodeJson", nodeJson);
		model.addObject("linkJson", linkJson);
		System.out.println(template.getName());
		System.out.println(template.getDescription());
		model.addObject("templateName", template.getName());
		model.addObject("templateDes", template.getDescription());
		model.addObject("templateGroup", template.getGroup()== null?0:template.getGroup().getId());
		if (aadlModel.getLogers() != null) {
			model.addObject("logerList", aadlModel.getLogers());
		}
		return model;
	}
	
	
	/**
	 * 提交更新架构模板的入口 
	 * @param uri
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/template/{uri}/update", method = RequestMethod.POST)
	public String updateAADLTemplatePost(@PathVariable(value = "uri") String uri,String aadl_xml, String name,
			long groupid,String logerInfo,
			String description,HttpServletResponse response) throws IOException {
		String aadlPath = Const.AADL_GENERATE_PATH;
		String aadlRealPath = Const.ABSOLUTE_GENERATE_PATH + aadlPath;
		Cookie uriCookie = new Cookie("uri", ""); //bake cookie	
		response.addCookie(uriCookie); //put cookie in response
		Cookie typeCookie = new Cookie("type", ""); //bake cookie	
		response.addCookie(typeCookie); //put cookie in response 
		String temp = "aadl_model" + new Timestamp().toString();
		MD5 md5 = new MD5();
		String fileName = md5.getMD5ofStr(temp).substring(0, 8);
		String filePath = aadlRealPath + "/" + fileName + ".xml";
		AADLTemplate aadlTemplate = aadlTemplateService.getAADLTemplateByUri(uri);
		AADLModel model = aadlTemplate.getModel();
		while (new File(filePath).exists()) {
			temp = "aadl_model" + new Timestamp().toString();
			fileName = md5.getMD5ofStr(temp).substring(0, 8);
			filePath = aadlRealPath + "/" + fileName + ".xml";
		}
		File file = getFile(filePath);
		FileWriter fWriter = null;
		try {
			fWriter = new FileWriter(file);
			fWriter.write(aadl_xml);

			AADLGenerator generator = new AADLGenerator();
			generator.generateAADL(aadl_xml, fileName + ".aadl");
			model.setAadlPath(aadlPath + fileName + ".aadl");
			model.setXmlPath(aadlPath + fileName + ".xml");
			aadlModelService.updateAADLModel(model);
			
			System.out.println("logerInfo:"+logerInfo);
			AADLLoger loger = new AADLLoger();
			loger.setLogInfo(logerInfo);
			loger.setModel(model);
			loger.setTime(new Date());
			Subject user = SecurityUtils.getSubject();
			if (user!= null && user.getPrincipals() != null) {
				CommonVariableModel commonVariableModel = (CommonVariableModel) user.getPrincipals()
						.getPrimaryPrincipal();
				loger.setOperator(commonVariableModel.getUser());
			}
			aadlLogerService.addAadlLoger(loger);
			
			PGroup group = pgroupService.getPGroupById(groupid);
			aadlTemplate.setGroup(group);
			aadlTemplate.setDescription(description);
			aadlTemplate.setName(name);
			aadlTemplateService.updateAADLTemplate(aadlTemplate);
			return "redirect:/aadl/template";
		} finally {
			fWriter.flush();
			fWriter.close();
		}
	}

	protected File getFile(String targetFileName) throws IOException {
		File targetFile = new File(targetFileName);
		if (!targetFile.getParentFile().exists()) {
			targetFile.getParentFile().mkdirs();
		}
		if (!targetFile.exists()) {
			targetFile.createNewFile();
		}
		return targetFile;
	}
}
